#!/bin/sh
#
# SPECIAL Upgrade tool to BSD Router Project 0.35
# http://bsdrp.net
#
# Copyright (c) 2009-2011, The BSDRP Development Team
# All rights reserved.
# Based on the updatep1 and updatep2 script of nanoBSD
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

#######################
##  Example of Usage ##
#######################	

# Put the bziped _.disk.image on my-server, in the  home dir of my-user,
# and from the nanoBSD device, enter this command:
# ssh my-user@my-server cat _.disk.image.bz2 | bzcat | upgrade

# Strict script
set -e
set -u

if ! grep -q "/dev/ufs/cfg" /etc/fstab; then
	echo "This script is for BSDRP release older than 0.35 only!"
	exit 1
fi

if [ ! -e /dev/ufs/cfg ]; then
	echo "This script is for BSDRP release older than 0.35 only!"
    exit 1
fi

ARCH=`uname -m`

if [ "${ARCH}" = "sparc64" ]; then
	echo "ERROR: upgrade script not adapted to ${ARCH}"
	exit 1
fi

# Get the NANO_GLABEL_SYS variable
# (get the name from mount output, and remove the last character)
NANO_GLABEL_SYS=`mount | grep " / " | cut -d'/' -f4 | cut -d' ' -f1 | sed 's/\(.*\)./\1/'`
# Get the NANO_GLABEL_SYS_FULL variable
# (kept the last 1 or 2 number)
NANO_GLABEL_SYS_FULL=`mount | grep " / " | cut -d'/' -f4 | cut -d' ' -f1`

# Get the disk name using its label
NANO_DRIVE=`glabel status | grep ufs/${NANO_GLABEL_SYS_FULL} | awk '{print $3}' | cut -d's' -f1`

# Get the full disk name
NANO_FULLDRIVE=`glabel status | grep ufs/${NANO_GLABEL_SYS_FULL} | awk '{print $3}'`

# Check and set final variable
DST_SLICE=0

if [ `echo $NANO_FULLDRIVE | /usr/bin/grep "s1"` ]; then 
	DST_SLICE=2
	SRC_SLICE=1
fi
if [ `echo $NANO_FULLDRIVE | /usr/bin/grep "s2"` ]; then                
    DST_SLICE=1
	SRC_SLICE=2
fi

if [ $DST_SLICE = 0 ]; then
	echo "Can't detect active slice"
	exit 1
fi

# Blow away old system.
if ! dd if=/dev/zero of=/dev/${NANO_DRIVE}s${DST_SLICE} bs=1m count=1 > /dev/null 2>&1; then
	echo "ERROR: Can't initialize destination partition"
	exit 1
fi

# This message disturb the ask for password from SSH
#echo "Upgrading... Please wait."

# Copy in new system
if ! dd of=/dev/${NANO_DRIVE}s${DST_SLICE} obs=64k; then
	echo "ERROR: Can't install the upgrade on slice ${DST_SLICE}"
	exit 1
fi

# Check that it worked
if ! fsck_ffs -n /dev/${NANO_DRIVE}s${DST_SLICE}a; then
	echo "ERROR: New file system check failed"
	exit 1
fi

# Set Label into the new slice
if ! tunefs -L ${NANO_GLABEL_SYS}s${DST_SLICE}a /dev/${NANO_DRIVE}s${DST_SLICE}a; then
	echo "ERROR: Can't put label on the new filesystem"
	exit 1
fi
if ! tunefs -L ${NANO_GLABEL_SYS}s3 /dev/${NANO_DRIVE}s3; then
	echo "ERROR: Can't replace old label on cfg slice"
	exit 1
fi
if ! tunefs -L ${NANO_GLABEL_SYS}s4 /dev/${NANO_DRIVE}s4; then
	echo "ERROR: Can't replace old label on data slice"
	exit 1
fi

# Need to compare some files between the old and new partition
if [ ! -d /tmp/upgrade ]; then
	mkdir /tmp/upgrade
fi
mount /dev/ufs/${NANO_GLABEL_SYS}s${DST_SLICE}a /tmp/upgrade
# 	Adapt fstab of the new system
for f in /tmp/upgrade/etc/fstab /tmp/upgrade/conf/base/etc/fstab /etc/fstab
	do
		sed -i "" "s/${NANO_GLABEL_SYS}${SRC_SLICE}/${NANO_GLABEL_SYS}s${DST_SLICE}a/g" $f
	    sed -i "" "s/${NANO_GLABEL_SYS}s${SRC_SLICE}a/${NANO_GLABEL_SYS}s${DST_SLICE}a/g" $f
		sed -i "" "s/\/dev\/ufs\/cfg/\/dev\/ufs\/${NANO_GLABEL_SYS}s3/g" $f
		#sed -i "" "s/\/dev\/ufs\/data/\/dev\/ufs\/${NANO_GLABEL_SYS}s4/g" $f	
    done
#	Compare the loader.conf, and include the diff into the new partition
#	This file is modify with "system virtualized"
if diff -ruN /boot/loader.conf /tmp/upgrade/boot/loader.conf > /tmp/loader.conf.patch; then
	if ! patch -s /tmp/upgrade/boot/loader.conf /tmp/loader.conf.patch; then
		echo "WARNING: Can't patch upgraded /boot/loader.conf"
		echo "YOU NEED to manually merge your /boot/loader.conf"
	fi
fi

if ! umount /tmp/upgrade; then
	echo "ERROR: Can't umount new image"
	exit 1
fi

if ! rm -r /tmp/upgrade; then
	echo "WARNING: Can't remove tempdir"
fi

# Save the config file that include the fstab
# Don't know if it's usefull
if ! mount /cfg; then
	echo "ERROR: Can't mount /cfg"
	exit 1
fi
if ! cp /etc/fstab /cfg; then
	echo "ERROR: Can't save fstab"
	umount /cfg
	exit 1
fi
if ! umount /cfg; then
	echo "ERROR: Can't umount /cfg"
	exit 1
fi

case "${ARCH}" in
        i386|amd64)
				boot0cfg -s ${DST_SLICE} -v ${NANO_DRIVE}
				gpart set -a active -i ${DST_SLICE} ${NANO_DRIVE}
                ;;
        arm)
				echo "arm upgrade script not tested!"	
				gpart set -a active -i ${DST_SLICE} ${NANO_DRIVE}
                ;;
        sparc64)
                echo "You need to configure OBP for booting on"
                ;;
esac

# Log
logger BSDRP Upgrade complete
